#include "StdAfx.h"

ShaderManager* Singleton<ShaderManager>::m_instance = NULL;

ShaderManager::ShaderManager(IDirect3DDevice9* pDevice) : mDevice(pDevice)
{
}

ID3DXEffect* ShaderManager::GetShader(const std::string& name)
{
	LPD3DXBUFFER errorBuffer = NULL;
	HMODULE curMod = GetModuleHandle(NULL);
	HRSRC res = FindResource(curMod, name.c_str(), MAKEINTRESOURCE(88));
	if(res == NULL)
		throw ShaderException("Unable to find shader in resources!");

	HGLOBAL glob = LoadResource(curMod, res);
	if(glob == NULL)
		throw ShaderException("Unable to load shader from resources!");

	LPSTR data = (LPSTR)LockResource(glob);
	ID3DXEffect* retVal;
	if(FAILED(D3DXCreateEffect(mDevice, data, SizeofResource(curMod, res), NULL, NULL, D3DXSHADER_OPTIMIZATION_LEVEL3, NULL, &retVal, &errorBuffer)))
		throw ShaderException((LPSTR)errorBuffer->GetBufferPointer());

	mEffects.insert(retVal);
	
	return retVal;
}

Shader& ShaderManager::getShader(const std::string& name) {
	if(mShaders.find(name) != mShaders.end())
		return *mShaders[name];

	auto eff = GetShader(name);
	mShaders[name] = new Shader(eff);
	return *mShaders[name];
}

void ShaderManager::onDeviceLost() {
	std::for_each(mEffects.begin(), mEffects.end(),
		[](ID3DXEffect* eff) { eff->OnLostDevice(); } );
}

void ShaderManager::onDeviceReset() {
	std::for_each(mEffects.begin(), mEffects.end(),
		[](ID3DXEffect* eff) { eff->OnResetDevice(); } );
}